<template>
  <TableLayout v-permissions="['system:user:query']">
    <!-- 搜索表单 -->
    <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="80px" inline>
      <el-form-item label="用户名">
        <el-input v-model="searchForm.username" placeholder="请输入用户名" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="姓名">
        <el-input v-model="searchForm.realname" placeholder="请输入姓名" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="手机号码">
        <el-input v-model="searchForm.mobile" placeholder="请输入手机号码" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <section>
        <el-button type="primary" @click="search" :loading="isWorking.search">搜索</el-button>
        <el-button @click="reset">重置</el-button>
      </section>
    </el-form>
    <!-- 表格和分页 -->
    <template v-slot:table-wrap>
      <ul class="toolbar">
        <li v-permissions="['system:user:create']"><el-button type="primary" @click="create">新建</el-button></li>
        <li v-permissions="['system:user:delete']"><el-button @click="deleteByIdInBatch">删除</el-button></li>
      </ul>
      <el-table
        :data="tableData.list"
        :default-sort = "{prop: 'date', order: 'descending'}"
        :loading="isWorking.search"
        stripe
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="55"></el-table-column>
        <el-table-column prop="avatar" label="头像" width="80px" class-name="table-column-avatar" fixed="left">
          <template slot-scope="{row}">
            <img :src="row.avatar == null ? '/static/avatar/man.png' : row.avatar">
          </template>
        </el-table-column>
        <el-table-column prop="realname" label="姓名" min-width="100px" fixed="left"></el-table-column>
        <el-table-column prop="username" label="用户名" min-width="100px"></el-table-column>
        <el-table-column prop="empNo" label="工号" min-width="80px"></el-table-column>
        <el-table-column prop="sex" label="性别" min-width="80px">
          <template slot-scope="{row}">
            {{row.sex | sex}}
          </template>
        </el-table-column>
        <el-table-column prop="email" label="邮箱" min-width="160px"></el-table-column>
        <el-table-column prop="mobile" label="手机号码" min-width="100px"></el-table-column>
        <el-table-column prop="birthday" label="生日" min-width="100px"></el-table-column>
        <el-table-column prop="birthday" label="角色" min-width="160px" class-name="table-column-role">
          <template slot-scope="{row}">
            <ul>
              <li v-for="role in row.roles" :key="role.id">{{role.name}}</li>
            </ul>
          </template>
        </el-table-column>
        <el-table-column prop="createTime" label="创建时间" min-width="140px"></el-table-column>
        <el-table-column prop="createUser" label="创建人" min-width="100px">
          <template slot-scope="{row}">{{row.createUserInfo == null ? '' : row.createUserInfo.username}}</template>
        </el-table-column>
        <el-table-column prop="updateTime" label="更新时间" min-width="140px"></el-table-column>
        <el-table-column prop="updateUser" label="更新人" min-width="100px">
          <template slot-scope="{row}">{{row.updateUserInfo == null ? '' : row.updateUserInfo.username}}</template>
        </el-table-column>
        <el-table-column label="操作" width="220" fixed="right">
          <template slot-scope="{row}">
            <el-button size="small" type="text" @click="edit(row)" v-permissions="['system:user:update']">编辑</el-button>
            <el-button size="small" type="text" @click="selectRole(row)" v-permissions="['system:user:createUserRole']">配置角色</el-button>
            <el-button size="small" type="text" @click="resetPwd(row)" >重置密码</el-button>
            <el-button size="small" type="text" @click="deleteById(row.id)" v-permissions="['system:user:delete']">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <pagination
        @size-change="handleSizeChange"
        @current-change="handlePageChange"
        :pagination="tableData.pagination">
      </pagination>
    </template>
    <!-- 添加/修改 -->
    <GlobalDialog
      class="opera-tabledata-dialog"
      :title="operaTableData.title"
      :visible.sync="visible.operaTable"
      :confirm-working="isWorking.create"
      @confirm="confirm"
      @close="close"
    >
      <el-form :model="operaTableData.form" ref="operaTableDataForm" :rules="operaTableData.rules">
        <el-form-item label="用户名" prop="username" required>
          <el-input v-model="operaTableData.form.username"></el-input>
        </el-form-item>
        <el-form-item label="姓名" prop="realname" required>
          <el-input v-model="operaTableData.form.realname"></el-input>
        </el-form-item>
        <el-form-item label="工号" prop="empNo">
          <el-input v-model="operaTableData.form.empNo"></el-input>
        </el-form-item>
        <el-form-item label="性别" prop="sex" required>
          <el-radio-group v-model="operaTableData.form.sex">
            <el-radio label="1">男</el-radio>
            <el-radio label="0">女</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="头像" prop="avatar" required>
          <el-radio-group v-model="operaTableData.form.avatar" class="form-item-avatar">
            <el-radio label="/static/avatar/man.png" border><img src="/static/avatar/man.png" alt=""></el-radio>
            <el-radio label="/static/avatar/woman.png" border><img src="/static/avatar/woman.png" alt=""></el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item v-if="operaTableData.form.id == null" label="密码" prop="password" required>
          <el-input type="password" v-model="operaTableData.form.password"></el-input>
        </el-form-item>
        <el-form-item label="邮箱" prop="email">
          <el-input v-model="operaTableData.form.email"></el-input>
        </el-form-item>
        <el-form-item label="手机号码" prop="mobile">
          <el-input v-model="operaTableData.form.mobile" maxlength="11"></el-input>
        </el-form-item>
        <el-form-item label="生日" prop="birthday">
          <el-date-picker v-model="operaTableData.form.birthday"/>
        </el-form-item>
      </el-form>
    </GlobalDialog>
    <!-- 配置角色 -->
    <GlobalDialog
      class="role-config-dialog"
      :visible.sync="visible.selectRole"
      :confirm-working="isWorking.selectRole"
      width="576px"
      title="配置用户角色"
      @confirm="confirmSelectRole"
      @close="visible.selectRole = false"
    >
      <p class="tip" v-if="selectRoleData.user != null">为用户 <em>{{selectRoleData.user.realname}}</em> 配置角色</p>
      <el-transfer
        v-model="selectRoleData.selectedIds"
        :titles="['未授权角色', '已授权角色']"
        :props="{
          key: 'id',
          label: 'name'
        }"
        :data="selectRoleData.roles">
      </el-transfer>
    </GlobalDialog>
    <!-- 重置密码 -->
    <GlobalDialog
      class="resetpwd-config-dialog"
      :visible.sync="visible.resetPwd"
      :confirm-working="isWorking.resetPwd"
      width="576px"
      title="重置密码"
      @confirm="confirmResetPwd"
      @close="visible.resetPwd = false"
    >
      <p class="tip" v-if="resetPwdData.user != null">为用户 <em>{{resetPwdData.user.realname}}</em> 重置密码</p>
      <el-form :model="resetPwdData.form" ref="resetPwdForm" :rules="resetPwdData.rules">
        <el-form-item label="新密码" prop="password" required>
          <el-input v-model="resetPwdData.form.password" type="password" placeholder="请输入新密码"></el-input>
        </el-form-item>
      </el-form>
    </GlobalDialog>
  </TableLayout>
</template>

<script>
import Pagination from '../../components/common/Pagination'
import GlobalDialog from '../../components/common/GlobalDialog'
import TableLayout from '../../layouts/TableLayout'
import {
  fetchList,
  create,
  updateById,
  deleteById,
  deleteByIdInBatch,
  createUserRole,
  resetPwd
} from '../../assets/api/system/systemUser'
import {fetchAll as fetchAllRoles} from '../../assets/api/system/systemRole'
import BaseTable from '../BaseTable'
import {checkEmail, checkMobile} from '../../assets/utils/form'

export default {
  name: 'SystemUser',
  extends: BaseTable,
  components: { TableLayout, GlobalDialog, Pagination },
  data () {
    return {
      // 是否展示
      visible: {
        selectRole: false,
        resetPwd: false
      },
      // 是否正在处理
      isWorking: {
        selectRole: false,
        resetPwd: false
      },
      // 搜索
      searchForm: {
        username: '', // 名字
        realname: '', // 姓名
        mobile: '' // 手机号码
      },
      // 新增/修改
      operaTableData: {
        title: '添加用户',
        // 表单数据
        form: {
          id: null,
          username: '', // 用户名
          realname: '', // 姓名
          empNo: '', // 工号
          avatar: '/static/avatar/man.png', // 头像
          password: '', // 密码
          mobile: '', // 手机号码
          email: '', // 邮箱
          sex: '1', // 性别
          birthday: '' // 生日
        },
        // 验证规则
        rules: {
          username: [
            { required: true, message: '请输入用户名' }
          ],
          realname: [
            { required: true, message: '请输入姓名' }
          ],
          password: [
            { required: true, message: '请输入密码' }
          ],
          avatar: [
            { required: true, message: '请选择用户头像' }
          ],
          sex: [
            { required: true, message: '请选择用户性别' }
          ],
          mobile: [
            { validator: checkMobile }
          ],
          email: [
            { validator: checkEmail }
          ]
        }
      },
      // 配置角色数据
      selectRoleData: {
        user: null,
        roles: [],
        selectedIds: []
      },
      // 重置密码
      resetPwdData: {
        user: null,
        form: {
          password: ''
        },
        rules: {
          password: [
            { required: true, message: '请输入密码' }
          ]
        }
      }
    }
  },
  methods: {
    // 确认创建/修改
    confirm () {
      if (this.operaTableData.form.id == null) {
        this.confirmCreate()
        return
      }
      this.confirmEdit()
    },
    // 添加
    create () {
      this.visible.operaTable = true
      this.operaTableData.title = '添加用户'
      this.$nextTick(() => {
        this.$refs.operaTableDataForm.resetFields()
      })
    },
    // 确定添加
    confirmCreate () {
      this.$refs.operaTableDataForm.validate((valid) => {
        if (!valid) {
          return
        }
        // 调用添加接口
        this.isWorking.operaTable = true
        create(this.operaTableData.form)
          .then(() => {
            this.visible.operaTable = false
            this.handlePageChange(1)
            this.$message.success('创建成功')
          })
          .catch(e => {
            this.$message.error(e.message)
          })
          .finally(() => {
            this.isWorking.operaTable = false
          })
      })
    },
    // 编辑
    edit (row) {
      Object.assign(this.operaTableData.form, row)
      this.operaTableData.title = '修改用户'
      this.visible.operaTable = true
    },
    // 确认修改
    confirmEdit () {
      this.$refs.operaTableDataForm.validate((valid) => {
        if (!valid) {
          return
        }
        // 调用添加接口
        this.isWorking.operaTable = true
        updateById(this.operaTableData.form)
          .then(() => {
            this.visible.operaTable = false
            this.search()
            this.$message.success('修改成功')
          })
          .catch(e => {
            this.$message.error(e.message)
          })
          .finally(() => {
            this.isWorking.operaTable = false
          })
      })
    },
    // 删除
    deleteById (id) {
      this.$confirm('确认删除此用户吗?', '提示', {
        confirmButtonText: '确认删除',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.isWorking.delete = true
        deleteById(id)
          .then(() => {
            this.$message.success('删除成功')
            // 删除当前页最后一条记录时查询上一页数据
            if (this.tableData.list.length - 1 === 0) {
              this.handlePageChange(this.tableData.pagination.pageIndex - 1 === 0 ? 1 : this.tableData.pagination.pageIndex - 1)
            } else {
              this.handlePageChange(this.tableData.pagination.pageIndex)
            }
          })
          .catch(e => {
            this.$message.error(e.message)
          })
          .finally(() => {
            this.isWorking.delete = false
          })
      })
    },
    // 批量删除
    deleteByIdInBatch () {
      if (this.tableData.selectedRows.length === 0) {
        this.$message.warning('请至少选择一条数据')
        return
      }
      this.$confirm(`确认删除已选中的 ${this.tableData.selectedRows.length} 条数据吗?`, '提示', {
        confirmButtonText: '确认删除',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.isWorking.delete = true
        deleteByIdInBatch(this.tableData.selectedRows.map(row => row.id).join(','))
          .then(() => {
            this.$message.success('删除成功')
            // 删除当前页最后一条记录时查询上一页数据
            if (this.tableData.list.length - 1 === 0) {
              this.handlePageChange(this.tableData.pagination.pageIndex - 1 === 0 ? 1 : this.tableData.pagination.pageIndex - 1)
            } else {
              this.handlePageChange(this.tableData.pagination.pageIndex)
            }
          })
          .catch(e => {
            this.$message.error(e.message)
          })
          .finally(() => {
            this.isWorking.delete = false
          })
      })
    },
    // 页码变更处理
    handlePageChange (pageIndex) {
      // 调用查询接口
      this.tableData.pagination.total = 0
      this.tableData.list.splice(0, this.tableData.list.length)
      this.isWorking.search = true
      fetchList({
        page: pageIndex,
        capacity: this.tableData.pagination.pageSize,
        model: this.searchForm
      })
        .then(data => {
          this.tableData.list = data.records
          this.tableData.pagination.total = data.total
        })
        .catch(e => {
          this.$message.error(e.message)
        })
        .finally(() => {
          this.isWorking.search = false
        })
    },
    // 选择角色
    selectRole (row) {
      fetchAllRoles()
        .then(records => {
          this.selectRoleData.user = row
          this.selectRoleData.roles = records
          this.selectRoleData.selectedIds = row.roles.map(r => r.id)
          this.visible.selectRole = true
        })
        .catch(e => {
          this.$message.error(e.message)
        })
    },
    // 确认选择角色
    confirmSelectRole () {
      if (this.isWorking.selectRole) {
        return
      }
      this.isWorking.selectRole = true
      createUserRole({
        userId: this.selectRoleData.user.id,
        roleIds: this.selectRoleData.selectedIds
      })
        .then(() => {
          this.$message.success('角色配置成功')
          this.visible.selectRole = false
          this.handlePageChange(1)
        })
        .catch(e => {
          this.$message.error(e.message)
        })
        .finally(() => {
          this.isWorking.selectRole = false
        })
    },
    // 重置密码
    resetPwd (row) {
      this.visible.resetPwd = true
      this.resetPwdData.user = row
      this.$nextTick(() => {
        this.$refs.resetPwdForm.resetFields()
      })
    },
    // 确认重置密码
    confirmResetPwd () {
      if (this.isWorking.resetPwd) {
        return
      }
      this.$refs.resetPwdForm.validate((valid) => {
        if (!valid) {
          return
        }
        this.isWorking.resetPwd = true
        resetPwd({
          id: this.resetPwdData.user.id,
          password: this.resetPwdData.form.password
        })
          .then(() => {
            this.$message.success('密码重置成功')
            this.visible.resetPwd = false
          })
          .catch(e => {
            this.$message.error(e.message)
          })
          .finally(() => {
            this.isWorking.resetPwd = false
          })
      })
    }
  },
  created () {
    this.search()
  }
}
</script>

<style scoped lang="less">
@import "../../assets/style/variable";
// 列表头像处理
.table-column-avatar {
  img {
    width: 48px;
  }
}
// 列表角色处理
.table-column-role {
  ul {
    li {
      display: inline-block;
      background: #eee;
      border-radius: 3px;
      padding: 0 3px;
      margin-right: 3px;
    }
  }
}
// 修改/新增数据
.opera-tabledata-dialog {
  /deep/ .el-radio-group {
    width: 100%;
  }
  /deep/ .el-date-editor {
    width: 100%;
  }
  // 表单头像处理
  .form-item-avatar {
    /deep/ .el-radio.is-bordered {
      height: auto;
      padding: 6px;
      margin: 0 10px 0 0;
      .el-radio__input {
        display: none;
      }
      .el-radio__label {
        padding: 0;
        width: 48px;
        display: block;
        img {
          width: 100%;
        }
      }
    }
  }
}
// 角色配置/重置密码
.role-config-dialog,
.resetpwd-config-dialog {
  .tip {
    margin-bottom: 12px;
    em {
      font-style: normal;
      color: @primary-color;
      font-weight: bold;
    }
  }
}
</style>
